﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotaHelp.Models;
using System.Threading;
using System.Text.RegularExpressions;
using DotaHelp.Helpers;
using System.ServiceModel.Syndication;
using MvcReCaptcha;

namespace DotaHelp.Controllers
{

    
    public class GuidesController : Controller
    {
        DotaModel model = new DotaModel();

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            model.Dispose();
            
        }
                
        public ActionResult List(int? page, string orderBy)
        {
             var guides = model.Guides.Include("Hero").Where(g=>!g.IsDeleted);
             return View(guides.ByPage(page, orderBy, p => p.Rating, p => p.Date, ViewData, HttpContext)); 
        }
                

        public ActionResult ListForHero(int heroId)
        {
            var guides = from g in model.Guides.Include("Hero")
                         where !g.IsDeleted && g.HeroId == heroId
                         orderby g.Rating descending, g.Date ascending
                         select g;

            return Request.IsAjaxRequest() ? (ActionResult)PartialView(guides.ToArray()) : View(guides.ToArray());
        }
        
        public ActionResult ChooseHero()
        {
            return View(model.Heroes);
        }

        public ActionResult Add(int id)
        {
            ViewBag.Hero = model.Heroes.First(h => h.Id == id);           
            return View(new Guide() { Author = Request.GetUserName(), HeroId = id, Id = 0 });
        }
          

        [HttpPost]
        [ValidateInput(false)]
		[CaptchaValidator]
        public ActionResult Add(int id, int heroId, Guide guide)
        {
            Response.SaveUserName(guide.Author);

            guide.HeroId = heroId;
            if (id == 0)
            {
                guide.Id = 0;
                guide.Rating = 0;               
            }
            else
            {
				var old = model.Guides.Include("GuidesTexts").First(g => g.Id == id);

                if (old.Password != guide.Password && !Request.IsAuthenticated)
                {
                    Thread.Sleep(1000);
					throw new MessageException("Неверный пароль");
                }

                model.UpdateFieldLogs.AddObject(new UpdateFieldLog() { Date = DateTime.Now, RowId = id, LastValue = old.GuideText.Text ?? "", NewValue = guide.GuideText.Text ?? "", TableName = "Guids", UserName = ControllerContext.HttpContext.PrepareUserName(Request.GetUserName()), FieldName = "Text" });

                model.DeleteObject(old.GuidesTexts.First());
                old.GuidesTexts.Clear();
                old.GuideText = guide.GuideText;
                //old.Password = guide.Password;
                old.Title = guide.Title;
                old.LangId = guide.LangId;
                old.Source = guide.Source;

                if (!Request.IsAuthenticated)
                {
                    old.Author = ControllerContext.HttpContext.PrepareUserName(guide.Author);
                }
                old.Version = guide.Version;
                guide = old;

                
            }

            
            guide.Date = DateTime.UtcNow.NowByAstana();
            

            guide.IpAddress = Request.ServerVariables["REMOTE_ADDR"];

            if (ModelState.IsValid)
            {                
                if (id == 0)
                {
                    model.Guides.AddObject(guide);                    
                }
                model.SaveChanges();            
                
                return Content(Url.RouteUrl("Guide", new { id = guide.Id }));  
            }

            ViewBag.Hero = model.Heroes.First(h => h.Id == guide.HeroId);
			return Content(string.Join(",", ModelState.Select(e => e.Value)));
        }

        public ActionResult Edit(int id, string password)
        {
			var guide = model.Guides.Include("GuidesTexts").First(g => g.Id == id);
            if (guide.Password == password || Request.IsAuthenticated)
            {
                ViewBag.Hero = model.Heroes.First(h => h.Id == guide.HeroId);
                return View("Add", guide);
            }

            Thread.Sleep(1000);
            throw new MessageException("Неверный пароль");             
        }

        [Sitemap(typeof(Guide), "Date")]
        public ActionResult Details(int id)
        {
			if (id == -1) return RedirectToAction("List");

            var guide = model.Guides.Include("Hero").Include("GuidesTexts").First(g => g.Id == id);

            var text = guide.GuideText.Text;

            text = Regex.Replace(text, @"onload=\"".*?\""", "");
            text = Regex.Replace(text, @"<input.*?>", "");
            text = Regex.Replace(text, @"\<script.*?\>", "");
            text = Regex.Replace(text, @"\</script>", "");

            ViewBag.CorrectText = text;

            return View(guide);
        }   
       
        [ChildActionOnly]
        public int Rating(int id, bool isPlus)
        {
            var guide = model.Guides.First(g => g.Id == id);
            guide.Rating += isPlus ? 1 : -1;
            model.SaveChanges();
            return guide.Rating;
        }

        [Authorize(Roles = "Admin")]
        public void Delete(int id)
        {
            var g = model.Guides.First(i => i.Id == id);
            g.IsDeleted = true;
            model.SaveChanges();           
        }
        
        [ChildActionOnly]
        [Rss]
        public IEnumerable<SyndicationItem> Rss()
        {
            var url = new UrlHelper(Request.RequestContext);

            foreach (var c in model.Guides.OrderByDescending(_ => _.Date).Take(50))
            {
                yield return new SyndicationItem("Гайд", c.Title, new Uri(url.GetBaseUrl(), url.Action("Details", "Guides", new { id = c.Id })), "g" + c.Id, c.Date);
            }
        }   

		[ChildActionOnly]
		public ActionResult One(Guide guide, bool showComments = false)
		{
			ViewData.Add("ShowHero", true);
			ViewData["ShowComments"] = showComments;
			return PartialView(guide);
		}
    }
}
